import { Ref, markRaw, ref } from "vue"
import BpmnModeler from 'bpmn-js/lib/Modeler'

// import propertiesPanelModule from 'bpmn-js-properties-panel';
// import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
// import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda';
// import CamundaExtensionModule from 'camunda-bpmn-moddle/lib';
// import camundaModdleDescriptors from 'camunda-bpmn-moddle/resources/camunda';
import customTranslate from './customTranslate/customTranslate'
import activitiModdleDescriptors from '/public/resource/bpmn/activiti-moddel.json'

// 导入一下有关于bpmn-js的字体库以及样式文件
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
// 右侧属性面包样式
import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'

// 两个属性面板相关模块
import { BpmnPropertiesPanelModule, BpmnPropertiesProviderModule, CamundaPlatformPropertiesProviderModule } from 'bpmn-js-properties-panel'

// bpmn-js-properties-panel相关
// import 'bpmn-js-properties-panel/dist/assets/element-templates.css'
// import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'
// import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css' // 右边工具栏样式

const bpmnModeler = ref();
/**
 * 初始化流程图
 */
export const bpmnInit = async (containerEl: Ref<HTMLElement | undefined>) => {
  console.log(containerEl.value)
  const customTranslateModule = {
    translate: ['value', customTranslate],
  }

  // 加markRaw去除双向绑定作用域
  bpmnModeler.value = markRaw(
    new BpmnModeler({
      container: containerEl.value,
      //添加控制板
      propertiesPanel: {
        parent: '#properties-panel',
      },
      additionalModules: [
        // 右边的属性栏
        // propertiesProviderModule,
        // propertiesPanelModule,

        BpmnPropertiesPanelModule,
        BpmnPropertiesProviderModule,
        CamundaPlatformPropertiesProviderModule,
        customTranslateModule,
      ],
      moddleExtensions: {
        activiti: activitiModdleDescriptors
      },
    })
  )

  try {
    const result = await bpmnModeler.value.createDiagram();
    const { warnings } = result;
    if (warnings?.length > 0) {
      console.log(warnings);
    } else {
      bpmnModeler.value.get('canvas').zoom('fit-viewport', 'auto');
    }
  } catch (err: any) {
    console.log(err.message, err.warnings);
  }

  // 监听节点选择变化
  bpmnModeler.value.on('selection.changed', (e) => {
    const element = e.newSelection[0]
    console.log('监听节点选择变化', element)
    console.log('监听节点选择变化', element?.id)
    console.log('监听节点选择变化', bpmnModeler.value)
    console.log('监听节点选择变化', bpmnModeler.value.getState())
  })

  //  监听节点属性变化
  bpmnModeler.value.on('element.changed', (e) => {
    const { element } = e
    console.log('监听节点属性变化', element)
  })
}

export const handlerImportXML = (xmlContent) => {
  bpmnModeler.value.importXML(xmlContent)
  const canvas = bpmnModeler.value.get('canvas')
  // 调整在正中间
  canvas.zoom('fit-viewport', 'auto')
}

let scale = 1

export const handlerRedo = () => {
  bpmnModeler.value.get('commandStack').redo()
}
export const handlerUndo = () => {
  bpmnModeler.value.get('commandStack').undo()
}
export const handlerZoom = (radio) => {
  const newScale = !radio ? 1.0 : scale + radio
  bpmnModeler.value.get('canvas').zoom(newScale)
  scale = newScale
}

export const beforeUpload = (file) => {
  // this.uploadBpmnFileList = [];
  openBpmn(file)
  return false
}

export const openBpmn = (file) => {
  const reader = new FileReader()
  // 读取File对象中的文本信息，编码格式为UTF-8
  reader.readAsText(file, 'utf-8')
  reader.onload = () => {
    // 读取完毕后将文本信息导入到Bpmn建模器
    // createNewDiagram(reader.result);
  }
  return false
}

export const downloadBpmn = () => {
  bpmnModeler.value.saveXML({ format: true }, (err, data) => {
    if (!err) {
      const xml = data.replace(/camunda.org\/schema\/1.0\/bpmn/ig, "activiti.org/bpmn").replace(/camunda/ig, "activiti");
      // 获取文件名
      const name = `${getFilename(xml)}.bpmn`
      // 将文件名以及数据交给下载方法
      download({ name: name, data: xml })
    }
  })
}

export const downloadSvg = (containerEl: Ref<HTMLElement>) => {
  bpmnModeler.value.saveXML({ format: true }, (err, data) => {
    if (!err) {
      const xml = data.replace(/camunda.org\/schema\/1.0\/bpmn/ig, "activiti.org/bpmn").replace(/camunda/ig, "activiti");
      // 获取文件名
      const name = `${getFilename(xml)}.svg`

      // 从建模器画布中提取svg图形标签
      let context = ''
      const djsGroupAll = containerEl.value?.querySelectorAll('.djs-group')
      if (djsGroupAll) {
        djsGroupAll.forEach((djsGroup) => {
          context += djsGroup.innerHTML
        })
      }
      // 获取svg的基本数据，长宽高
      const viewport: any = containerEl.value?.querySelector('.viewport')
      console.log('获取svg的基本数据，长宽高', viewport);

      // 将标签和数据拼接成一个完整正常的svg图形
      const svg = `<svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            width="${viewport?.width}"
            height="${viewport?.height}"
            viewBox="${viewport?.x} ${viewport?.y} ${viewport?.width} ${viewport?.height}"
            version="1.1"
            >
            ${context}
          </svg>`
      // 将文件名以及数据交给下载方法
      download({ name: name, data: svg })
    }
  })
}

const download = ({ name = 'diagram.bpmn', data }) => {
  console.log(data)
  // 把输就转换为URI，下载要用到的
  const encodedData = encodeURIComponent(data)

  if (data) {
    const downloadLink = document.createElement('a')
    // 将数据给到链接
    downloadLink.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
    // 设置文件名
    downloadLink.download = name
    // 触发点击事件开始下载
    downloadLink.click()
    downloadLink.remove()
  }
}

const getFilename = (xml) => {
  let start = xml.indexOf('process')
  let filename = xml.substr(start, xml.indexOf('>'))
  filename = filename.substr(filename.indexOf('id') + 4)
  filename = filename.substr(0, filename.indexOf('"'))
  return filename
}
